/*
 * @Author: 0x9DEFA478
 * @Date: 2021-07-31 17:04:53
 * @LastEditTime: 2021-09-08 12:09:41
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "H_UI.h"





static void NextPage(H_UI* h_ui){
  H_UI_Page* p;
  H_UI_Page* p_next;

  if(h_ui->EmptyPage->List.Next==h_ui->EmptyPage->List.Last){
    return;
  }

  p=h_ui->Page;
  p_next=p->List.Next;
  while(p_next==h_ui->EmptyPage){
    p_next=p_next->List.Next;
  }

  if(p==p_next){
    //只有一个页面
    return;
  }

  h_ui->Page=p_next;
  
  p->Callbacks.ExitPageCallback(p);
  h_ui->NextPageCallback(h_ui,p,p_next);
  p_next->Callbacks.EnterPageCallback(p_next);

}

static void LastPage(H_UI* h_ui){
  H_UI_Page* p;
  H_UI_Page* p_last;

  if(h_ui->EmptyPage->List.Next==h_ui->EmptyPage->List.Last){
    return;
  }

  p=h_ui->Page;
  p_last=p->List.Last;
  while(p_last==h_ui->EmptyPage){
    p_last=p_last->List.Last;
  }

  if(p==p_last){
    //只有一个页面
    return;
  }

  h_ui->Page=p_last;
  
  
  p->Callbacks.ExitPageCallback(p);
  h_ui->LastPageCallback(h_ui,p,p_last);
  p_last->Callbacks.EnterPageCallback(p_last);

}


/**
 * @brief 获得一个新的H_UI
 * @param Malloc 内存申请方法
 * @param Free 内存释放方法
 * @return 新的H_UI 如果为NULL 则为失败
 */
H_UI* new_H_UI(void* (*Malloc)(Husize),void (*Free)(void*)
  ,void (*NextPageCallback)(struct _H_UI*,H_UI_Page*,H_UI_Page*),void (*LastPageCallback)(struct _H_UI*,H_UI_Page*,H_UI_Page*)){
  H_UI* h_ui;

  h_ui=Malloc(sizeof(H_UI));
  if(h_ui==NULL){
    return NULL;
  }

  h_ui->EmptyPage=Malloc(sizeof(H_UI_Page));
  if(h_ui->EmptyPage==NULL){
    Free(h_ui);
    return NULL;
  }

  h_ui->Memory.Malloc=Malloc;
  h_ui->Memory.Free=Free;
  h_ui->Page=h_ui->EmptyPage;
  h_ui->IsSelect=0;
  h_ui->NextPageCallback=NextPageCallback;
  h_ui->LastPageCallback=LastPageCallback;
  h_ui->UserInstence=NULL;

  //环形链表
  h_ui->EmptyPage->List.Last=h_ui->EmptyPage;
  h_ui->EmptyPage->List.Next=h_ui->EmptyPage;

  h_ui->EmptyPage->Parent=h_ui;
  h_ui->EmptyPage->UserInstence=NULL;
  h_ui->EmptyPage->Callbacks.BackCallback=NULL;
  h_ui->EmptyPage->Callbacks.EnterCallback=NULL;
  h_ui->EmptyPage->Callbacks.AddCallback=NULL;
  h_ui->EmptyPage->Callbacks.SubCallback=NULL;
  h_ui->EmptyPage->Callbacks.EnterPageCallback=NULL;
  h_ui->EmptyPage->Callbacks.ExitPageCallback=NULL;
  h_ui->EmptyPage->Callbacks.DisplayPageCallback=NULL;

  return h_ui;
}

/**
 * @brief 删除 H_UI 会将其下的节点删除
 * @param h_ui 要删除的H_UI
 * @return 无
 */
void delete_H_UI(H_UI* h_ui){
  H_UI_Page* p;
  H_UI_Page* p_next;

  p=h_ui->Page;

  while(h_ui->EmptyPage->List.Next!=h_ui->EmptyPage->List.Last){
    p_next=p->List.Next;

    if(p!=h_ui->EmptyPage){
      H_UI_DeletePage(p);
    }

    p=p_next;
  }

  h_ui->Memory.Free(h_ui->EmptyPage);
  h_ui->Memory.Free(h_ui);
}

/**
 * @brief 添加H_UI新页面 添加到参考页面对象之后
 * @param h_ui H_UI对象
 * @param ref 参考页面
 * @return 新的页面对象 如果为NULL 则新建失败
 */
H_UI_Page* H_UI_NewPage(H_UI* h_ui,H_UI_Page* ref,H_UI_Callbacks* Callbacks){
  H_UI_Page* r;
  H_UI_Page* p_next;
  H_UI_Page* p_last;

  r=h_ui->Memory.Malloc(sizeof(H_UI_Page));
  if(r==NULL){
    return NULL;
  }

  r->Callbacks=*Callbacks;
  r->Parent=h_ui;
  r->UserInstence=NULL;//此段默认为NULL

  p_next=ref->List.Next;
  p_last=ref;
  r->List.Last=p_last;
  r->List.Next=p_next;
  p_last->List.Next=r;
  p_next->List.Last=r;
  
  if(h_ui->Page==h_ui->EmptyPage){
    h_ui->Page=r;
    r->Callbacks.EnterPageCallback(r);
  }

  return r;
}

/**
 * @brief 删除H_UI_Page页面
 * @param h_ui_page 要删除的页面
 * @return 无
 */
void H_UI_DeletePage(H_UI_Page* h_ui_page){
  H_UI_Page* p_last;
  H_UI_Page* p_next;
  H_UI* h_ui;

  h_ui=h_ui_page->Parent;

  if(h_ui_page==h_ui->EmptyPage){
    //空页面不能删除
    return;
  }

  if(h_ui_page==h_ui->Page){
    //删除的是正在显示的页面

    NextPage(h_ui);

    if(h_ui_page==h_ui->Page){
      //无变化
      h_ui->Page=h_ui->EmptyPage;
      h_ui_page->Callbacks.ExitPageCallback(h_ui_page);
    }
  }

  //将页面移出
  p_last=h_ui_page->List.Last;
  p_next=h_ui_page->List.Next;
  p_last->List.Next=p_next;
  p_next->List.Last=p_last;

  h_ui->Memory.Free(h_ui_page);

}

/**
 * @brief 获取H_UI的空页面(空页面不参与显示,仅用于占位置)
 * @param h_ui 要获取的对象
 * @return 空页面
 */
H_UI_Page* H_UI_GetEmptyPage(H_UI* h_ui){
  return h_ui->EmptyPage;
}

/**
 * @brief 使h_ui退出页面选中状态 一般在BackCallback中调用它
 * @param h_ui 操作的h_ui
 * @return 无
 */
void H_UI_ExitSelect(H_UI* h_ui){
  h_ui->IsSelect=0;
}

/**
 * @brief 使h_ui进入页面选中状态 一般在DisplayPageCallback中调用它
 * @param h_ui 操作的h_ui
 * @return 无
 */
void H_UI_EnterSelect(H_UI* h_ui){
  h_ui->IsSelect=-1;
}

/**
 * @brief 通过调用这个方法传入返回事件
 * @param h_ui 操作的h_ui
 * @return 无
 */
void H_UI_BackEvent(H_UI* h_ui){

  if(h_ui->IsSelect==0){
    
  }else{
    if(h_ui->Page!=h_ui->EmptyPage){
      h_ui->Page->Callbacks.BackCallback(h_ui->Page);
    }
  }
}

/**
 * @brief 通过调用这个方法传入确认事件
 * @param h_ui 操作的h_ui
 * @return 无
 */
void H_UI_EnterEvent(H_UI* h_ui){

  if(h_ui->IsSelect==0){
    h_ui->IsSelect=-1;
  }else{
    if(h_ui->Page!=h_ui->EmptyPage){
      h_ui->Page->Callbacks.EnterCallback(h_ui->Page);
    }
  }
}

/**
 * @brief 通过调用这个方法传入减少事件
 * @param h_ui 操作的h_ui
 * @return 无
 */
void H_UI_SubEvent(H_UI* h_ui){

  if(h_ui->IsSelect==0){
    LastPage(h_ui);
  }else{
    if(h_ui->Page!=h_ui->EmptyPage){
      h_ui->Page->Callbacks.SubCallback(h_ui->Page);
    }
  }
}

/**
 * @brief 通过调用这个方法传入增加事件
 * @param h_ui 操作的h_ui
 * @return 无
 */
void H_UI_AddEvent(H_UI* h_ui){

  if(h_ui->IsSelect==0){
    NextPage(h_ui);
  }else{
    if(h_ui->Page!=h_ui->EmptyPage){
      h_ui->Page->Callbacks.AddCallback(h_ui->Page);
    }
  }
}


/**
 * @brief 调用正在显示页面的显示方法
 * @param h_ui 操作的h_ui
 * @return 无
 */
void H_UI_Page_Display(H_UI* h_ui){

  if(h_ui->Page==h_ui->EmptyPage)
  {
    return;
  }
  
  h_ui->Page->Callbacks.DisplayPageCallback(h_ui->Page);

}


